// 处理并发请求任务最大不超过max个，可以最大执行任务

function Task(i) {
  // 必须先返回一个函数，函数再返回Promise实例
  // 如果直接返回Promise实例，是增加的Promise运行时的状态，全部任务会同时执行掉
  return () =>
  new Promise((resolve, reject) => {
    setTimeout(() => resolve(i), 1000);
  });
}
class Queue {
  constructor(max) {
    this.max = max;
    this.taskList = [];
    // 设置一个自动开始执行任务
    setTimeout(() => this.run());
  }
  
  addTask(task) {
    this.taskList.push(task);
  }
  run() {
    let len = this.taskList.length;
    // 取队列长度和max中的最小值，该最小值就是一次执行的数量
    let min = Math.min(this.max, len);
    if (!len) return;
    for (let i = 0; i < min; i++) {
      this.max--;
      let task = this.taskList.shift();
      task()
        .then((res) => console.log(res))
        .catch((err) => console.log(err))
        .finally(() => {
        this.max++;
        // 继续执行run方法
        this.run();
      });
    }
  }
}

let queue = new Queue(7);
for (let i = 0; i < 20; i++) {
  const task = Task(i);
  queue.addTask(task);
}